/**
 * file:   main_loop_stm32_raw.c
 * author: li xianjing <xianjimli@hotmail.com>
 * brief:  main loop for stm32
 *
 * copyright (c) 2018 - 2018 Guangzhou ZHIYUAN Electronics Co.,Ltd. 
 *
 * this program is distributed in the hope that it will be useful,
 * but without any warranty; without even the implied warranty of
 * merchantability or fitness for a particular purpose.  see the
 * license file for more details.
 *
 */

/**
 * history:
 * ================================================================
 * 2018-05-11 li xianjing <xianjimli@hotmail.com> created
 *
 */
#include "gd32h7xx.h"
#include "stdbool.h"
#include "base/g2d.h"
#include "base/idle.h"
#include "base/timer.h"
#include "lcd/lcd_mem.h"
#include "tkc/mem.h"
#include "base/lcd.h"
#include "lcd/lcd_mem_bgr565.h"
#include "lcd/lcd_mem_fragment.h"
#include "main_loop/main_loop_simple.h"
#include "stdio.h"
#include "math.h"

#include "gd32h759i_eval_tsc2007_ts.h"
#include "systick.h"

/*LCD缓存指针在此处被定义*/
extern __ALIGNED(16) uint16_t display_memory_front[];
extern __ALIGNED(16) uint16_t display_memory_back[];

extern bool g_touchevent;
extern void DrawSquareToFrame(uint32_t baseaddress,uint32_t x,uint32_t y,uint32_t w,uint32_t h,lcdSize_t lcdSize);
extern uint32_t sysCurrentTime;

volatile static bool s_frameDone = FALSE;

volatile static bool start_swap = FALSE;

void cleanDCache(void)
{
	SCB_CleanInvalidateDCache();
}

touchPoint_t touchPoint;
touchPoint_t touchPointTest[2] = {0};
uint8_t platform_disaptch_input(main_loop_t* loop) {
	static xy_t last_x = 0;
	static xy_t last_y = 0;
	TS_StateTypeDef  ts;
	static uint32_t last_time = 0;
	uint32_t current_time = 0;
	current_time = sysCurrentTime;
	
	if((current_time-last_time)>30)
	{
		BSP_TS_GetState(&ts);
		if(ts.touchDetected)
		{
			last_x = ts.touchX[0];
			last_y = ts.touchY[0];
			main_loop_post_pointer_event(loop, TRUE,last_x,last_y);	
		}
		else{
    /*Set the last pressed coordinates*/
		main_loop_post_pointer_event(loop, FALSE,last_x,last_y);	
		}
		last_time = current_time;
	}
	
	return 0;
}

lcd_t* lcd = NULL;

uint32_t Current_fb = (uint32_t)display_memory_front;//现在需要显示的显存是哪个

#if USE_LCD_SYNC
extern void layerSetNextBuf(uint32_t bufaddr);
void TLI_IRQHandler(void)
{
	FlagStatus status;
	status = tli_interrupt_flag_get(TLI_INT_FLAG_LCR);
	tli_interrupt_flag_clear(TLI_INT_FLAG_LCR);
	
#if USE_LCD_SYNC 
    
    s_frameDone = TRUE;
    
#endif  
    
}
#endif
extern volatile uint32_t sync_ms;
volatile static bool swap_end = FALSE;
ret_t lcd_mem_swap(lcd_t* lcd)
{
    uint32_t start_sync_time = 0;
    lcd_mem_t* mem = (lcd_mem_t*)lcd;
    uint8_t* temp_fb = mem->offline_fb;     
    
    Current_fb = (uint32_t)temp_fb;    
    layerSetNextBuf(Current_fb);/*受限于sdram的性能，将绘图与显示错开，避免CPU和TLI外设同时使用SDRAM*/
    s_frameDone = FALSE;
    start_sync_time = sync_ms;
#if USE_LCD_SYNC
    while(s_frameDone == FALSE){
        if((sync_ms - start_sync_time)>85)//若til推图出现
        {
           sync_ms = 0;
           break;
        }
    };
    s_frameDone = FALSE;
#endif
    
    lcd_mem_set_offline_fb(mem,mem->online_fb);
    lcd_mem_set_online_fb(mem,temp_fb);        
    
    return RET_OK;
}


ret_t lcd_mem_sync(lcd_t* lcd)
{
    return RET_OK;
}

static ret_t main_loop_dispatch(main_loop_simple_t* loop) {
	 
	return RET_OK;
}

lcd_t* platform_create_lcd(wh_t w, wh_t h) {
		lcd_t* lcd = NULL;
		lcd = lcd_mem_bgr565_create_double_fb(w, h,(uint8_t*)&display_memory_front[0],(uint8_t*)&display_memory_back[0]);//开辟双缓存
#if USE_LCD_SYNC        
        lcd->swap = lcd_mem_swap;
        lcd->support_dirty_rect = FALSE;
        lcd->sync = lcd_mem_sync;
#endif
        lcd->sync = lcd_mem_sync;
		return lcd;
}
#include "main_loop/main_loop_raw.inc"